package com.zzyl.nursing.service.impl;

import java.time.LocalDateTime;
import java.time.OffsetDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.huaweicloud.sdk.iotda.v5.IoTDAClient;
import com.huaweicloud.sdk.iotda.v5.model.*;
import com.zzyl.common.constant.CacheConstants;
import com.zzyl.common.exception.base.BaseException;
import com.zzyl.common.utils.DateUtils;
import com.zzyl.common.utils.StringUtils;
import com.zzyl.nursing.dto.DeviceDto;
import com.zzyl.nursing.vo.health.DeviceDetailVo;
import com.zzyl.nursing.vo.health.ProductVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import com.zzyl.nursing.mapper.DeviceMapper;
import com.zzyl.nursing.domain.Device;
import com.zzyl.nursing.service.IDeviceService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

/**
 * 设备Service业务层处理
 * 
 * @author alexis
 * @date 2025-06-17
 */
@Service
public class DeviceServiceImpl extends ServiceImpl<DeviceMapper, Device> implements IDeviceService
{
    @Autowired
    private DeviceMapper deviceMapper;

    /**
     * 查询设备
     * 
     * @param id 设备主键
     * @return 设备
     */
    @Override
    public Device selectDeviceById(Long id)
    {
        return deviceMapper.selectById(id);
    }

    /**
     * 查询设备列表
     * 
     * @param device 设备
     * @return 设备
     */
    @Override
    public List<Device> selectDeviceList(Device device)
    {
        return deviceMapper.selectDeviceList(device);
    }

    /**
     * 新增设备
     * 
     * @param device 设备
     * @return 结果
     */
    @Override
    public int insertDevice(Device device)
    {
        return deviceMapper.insert(device);
    }

    /**
     * 修改设备
     * 
     * @param device 设备
     * @return 结果
     */
    @Override
    public int updateDevice(Device device)
    {
        return deviceMapper.updateById(device);
    }

    /**
     * 批量删除设备
     * 
     * @param ids 需要删除的设备主键
     * @return 结果
     */
    @Override
    public int deleteDeviceByIds(Long[] ids)
    {
        return deviceMapper.deleteBatchIds(Arrays.asList(ids));
    }

    /**
     * 删除设备信息
     * 
     * @param id 设备主键
     * @return 结果
     */
    @Override
    public int deleteDeviceById(Long id)
    {
        return deviceMapper.deleteById(id);
    }


    @Autowired
    private IoTDAClient client;

    @Autowired
    private  RedisTemplate redisTemplate;
    @Override
    public void syncProductList() {
        ListProductsRequest request = new ListProductsRequest();
        //调用华为云的接口
        ListProductsResponse listProductsResponse = client.listProducts(request);

        if(listProductsResponse.getHttpStatusCode()!=200){
            throw new BaseException("同步产品列表失败");
        }
        List<ProductSummary> products = listProductsResponse.getProducts();
        //存入redis
        redisTemplate.opsForValue().set(CacheConstants.PRODUCT_LIST_KEY, JSONUtil.toJsonStr(products));

    }

    @Override
    public List<ProductVo> allProduct() {
       //从redis中获取
        String products = (String) redisTemplate.opsForValue().get(CacheConstants.PRODUCT_LIST_KEY);
        //加一个非空判断
        if(StrUtil.isEmpty( products)){
            return  new ArrayList<>();

        }
        return JSONUtil.toList(products,ProductVo.class);
    }

    @Override
    public void registerDevice(DeviceDto dto) {
        /*首先是三个判断*/
        //1.判断设备名称时候存在
        Long count1= lambdaQuery()
                .eq(Device::getDeviceName, dto.getDeviceName())
                .count();
        if (count1!=null && count1 >0){
            throw new BaseException("设备名称已存在");

        }
        //2.设备标识是否重复
        Long count2 = lambdaQuery()
                .eq(Device::getNodeId, dto.getNodeId())
                .count();
        if (count2!=null && count2 >0) {
            throw new BaseException("设备id已存在");
        }

        //3.同一位置是否绑定了相同的产品
            Long count3 = lambdaQuery()
                    .eq(Device::getBindingLocation, dto.getBindingLocation())
                    .eq(Device::getLocationType, dto.getLocationType())
                    .eq(Device::getPhysicalLocationType, dto.getPhysicalLocationType())
                    .eq(Device::getDeviceDescription, dto.getDeviceDescription())
                    .count();
        if (count3!=null && count3 >0){
            throw new BaseException("同一位置已绑定过产品产品");
        }
        AddDeviceRequest request = new AddDeviceRequest();
        AddDevice body = new AddDevice();
        body.withProductId(dto.getProductKey());
        body.withDeviceName(dto.getDeviceName());
        body.withNodeId(dto.getNodeId());
        request.withBody(body);
        AuthInfo authInfo = new AuthInfo();
        //秘钥
        String secret = UUID.randomUUID().toString().replaceAll("-", "");
        authInfo.withSecret(secret);
        body.setAuthInfo(authInfo);
        AddDeviceResponse response;
        AddDeviceResponse addDeviceResponse = client.addDevice(request);
        try {

        } catch (Exception e) {
            throw new RuntimeException("调用华为云失败");
        }

        //存到数据库
        Device bean = BeanUtil.toBean(dto, Device.class);
        bean.setHaveEntranceGuard(0);
        bean.setSecret(secret);
        bean.setIotId(addDeviceResponse.getDeviceId());
        save( bean);


    }

    /**
     * 查询设备详情
     * @param iotId
     * @return
     */

    @Override
    public DeviceDetailVo queryDeviceDetail(String iotId) {
        //先查询数据库
        Device device1 = lambdaQuery()
                .eq(Device::getIotId, iotId)
                .one();
        //再拷贝到vo
        DeviceDetailVo vo = BeanUtil.toBean(device1, DeviceDetailVo.class);
        //查询设备详情
        //先查询华为云
        ShowDeviceRequest request = new ShowDeviceRequest();
        request.setDeviceId(iotId);
        ShowDeviceResponse device;
        try {
             device = client.showDevice(request);
        } catch (Exception e) {
            throw new RuntimeException("调用华为云失败");
        }
        //把华为云里的数据取出来
        String status = device.getStatus();
        String activeTime = device.getActiveTime();
        vo.setDeviceStatus(status);
        OffsetDateTime offsetDateTime= OffsetDateTime.parse(activeTime);
        LocalDateTime beijingDateTime=offsetDateTime
                .atZoneSameInstant(ZoneId.of("Asia/Shanghai"))
                .toLocalDateTime();
                vo.setActiveTime(beijingDateTime);

        return vo;



        //最后返回华为云和数据库的结果

    }
}

